package onlinesig

import (
	"bytes"
	"crypto/md5"
	"crypto/sha1"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"mime/multipart"
	"net/http"
	"strings"
	"time"
	"yundian/internel/app/helper/request"
	"yundian/internel/pkg/dingo/global"
)

// ------------ 法大大请求 -----------------//

type OnlineSig struct {
}

func NewOnlineSig() *OnlineSig {
	return &OnlineSig{}
}

//FormData Get参数提交

func (sig *OnlineSig) GetWithFormData(url string, postData *map[string]string) (map[string]interface{}, error) {
	respMap := make(map[string]interface{})
	body := new(bytes.Buffer)
	w := multipart.NewWriter(body)
	for k, v := range *postData {
		w.WriteField(k, v)
	}
	w.Close()
	req, err := http.NewRequest("GET", url, body)
	if err != nil {
		return nil, err
	}
	//for h, v := range headers {
	//	req.Header.Set(h, v)
	//}
	req.Header.Set("Content-Type", w.FormDataContentType())

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("http.Status: %s", resp.Status)
	}

	result, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()

	err = json.Unmarshal(result, &respMap)
	if err != nil {
		return nil, err
	}
	return respMap, nil
}

//FormData Post参数提交
func (sig *OnlineSig) PostWithFormData(url string, postData *map[string]string, headers map[string]string) (map[string]interface{}, error) {
	//headers map[string]string
	respMap := make(map[string]interface{})
	body := new(bytes.Buffer)

	w := multipart.NewWriter(body)
	//表单字段
	for k, v := range *postData {
		w.WriteField(k, v)
	}
	w.Close()

	req, err := http.NewRequest("POST", url, body)
	if err != nil {
		return nil, err
	}
	for h, v := range headers {
		req.Header.Set(h, v)
	}

	req.Header.Set("Content-Type", w.FormDataContentType())

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("http.Status: %s", resp.Status)
	}

	result, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()

	err = json.Unmarshal(result, &respMap)
	if err != nil {
		return nil, err
	}
	return respMap, nil
}

//FormData Post参数提交
func (sig *OnlineSig) PostWithFormDataReturnByte(url string, postData *map[string]string, headers map[string]string) ([]byte, error) {
	//headers map[string]string
	//respMap := make(map[string]interface{})
	body := new(bytes.Buffer)

	w := multipart.NewWriter(body)
	//表单字段
	for k, v := range *postData {
		w.WriteField(k, v)
	}
	w.Close()

	req, err := http.NewRequest("POST", url, body)
	if err != nil {
		return nil, err
	}
	for h, v := range headers {
		req.Header.Set(h, v)
	}

	req.Header.Set("Content-Type", w.FormDataContentType())

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("http.Status: %s", resp.Status)
	}

	result, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()

	//err = json.Unmarshal(result, &respMap)
	//if err != nil {
	//	return nil, err
	//}
	return result, nil
}

//FormData Post 含有文件参数提交
func (sig *OnlineSig) PostWithFileFormData(url string, postData *map[string]string, headers map[string]string, fileMap map[string]string) (map[string]interface{}, error) {
	//headers map[string]string
	respMap := make(map[string]interface{})
	var errStr string
	body := new(bytes.Buffer)

	w := multipart.NewWriter(body)
	//表单字段
	for k, v := range *postData {
		w.WriteField(k, v)
	}
	//文件
	for fileKey, fileVal := range fileMap {
		writerFile, err := w.CreateFormFile(fileKey, fileVal)
		if err != nil {
			errStr = fmt.Sprintf("创建文件失败:%s", err)
			return nil, errors.New(errStr)
		}
		fileData, err := ioutil.ReadFile(fileVal)
		if err != nil {
			errStr = fmt.Sprintf("读取图片发生错误:%s", err)
			return nil, errors.New(errStr)
		}
		writerFile.Write(fileData)
	}

	w.Close()

	req, err := http.NewRequest("POST", url, body)
	if err != nil {
		return nil, err
	}
	for h, v := range headers {
		req.Header.Set(h, v)
	}

	req.Header.Set("Content-Type", w.FormDataContentType())

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("http.Status: %s", resp.Status)
	}

	result, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()

	err = json.Unmarshal(result, &respMap)
	if err != nil {
		return nil, err
	}
	return respMap, nil
}

func SHA1(s string) string {

	o := sha1.New()

	o.Write([]byte(s))

	return hex.EncodeToString(o.Sum(nil))

}
func MD5(str string) string {
	data := []byte(str)
	has := md5.Sum(data)
	md5Str := fmt.Sprintf("%x", has)
	return md5Str
}
func Base64(str string) string {
	// 进行加密
	base64Str := base64.StdEncoding.EncodeToString([]byte(str))
	return base64Str
}

func RandomStr(l int) string {
	str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	bytes := []byte(str)
	result := make([]byte, 0)
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < l; i++ {
		result = append(result, bytes[r.Intn(len(bytes))])
	}
	return string(result)
}

func MsgDigestStr(appId string, appSecret string, accountType string, openId string, timeStr string) string {
	shaStr1 := strings.ToTitle(SHA1(appSecret + accountType + openId))
	//md5Str := strings.ToTitle(MD5(time.Now().Format("20060102030405")))
	md5Str := strings.ToTitle(MD5(timeStr))
	fmt.Println("shaStr1", shaStr1, "Md5", md5Str)

	shaStr2 := SHA1(strings.ToTitle(appId) + md5Str + shaStr1)
	msgDigest := Base64(strings.ToTitle(shaStr2))
	return msgDigest
}

//注册账号
func AccountRegister(openId string, accountType string) map[string]interface{} {
	accountRegisterModel := &request.AccountRegisterReq{}

	postData := map[string]string{}

	//accountType = "1"
	//openId = RandomStr(32)
	timeStr := time.Now().Format("20060102030405")

	//获取MsgDigest
	shaStr1 := strings.ToTitle(SHA1(global.Cfg.Fdd.FddAppSecret + accountType + openId))
	//md5Str := strings.ToTitle(MD5(time.Now().Format("20060102030405")))
	md5Str := strings.ToTitle(MD5(timeStr))
	fmt.Println("shaStr1", shaStr1, "Md5", md5Str)

	shaStr2 := SHA1(strings.ToTitle(global.Cfg.Fdd.FddAppId) + md5Str + shaStr1)
	msgDigest := Base64(strings.ToTitle(shaStr2))

	accountRegisterModel.AppId = global.Cfg.Fdd.FddAppId
	accountRegisterModel.Timestamp = timeStr
	accountRegisterModel.OpenId = openId
	accountRegisterModel.AccountType = accountType
	accountRegisterModel.V = "2.0"
	accountRegisterModel.MsgDigest = msgDigest

	//转为Map
	dataByte, _ := json.Marshal(&accountRegisterModel)
	json.Unmarshal(dataByte, &postData)

	//测试环境
	urlStr := "https://textapi.fadada.com/api2/account_register.api"
	data, err := NewOnlineSig().PostWithFormData(urlStr, &postData, nil)
	if err != nil {
		return nil
	}
	return data
}

//获取个人实名认证地址
func GetPersonVerifyUrl(param request.GetPersonVerifyUrl) map[string]interface{} {

	postData := map[string]string{}
	//获取MsgDigest
	shaStr1 := strings.ToTitle(SHA1(global.Cfg.Fdd.FddAppSecret + param.BankCardNo + param.CertFlag + param.CertType + param.CustomerId + param.CustomerIdentNo +
		param.CustomerIdentType + param.CustomerName + param.IdentBackPath + param.IdentFrontPath + param.Mobile + param.NotifyUrl + param.PageModify +
		param.ResultType + param.ReturnUrl + param.VerifiedWay))
	timeStr := time.Now().Format("20060102030405")
	md5Str := strings.ToTitle(MD5(timeStr))
	shaStr2 := SHA1(strings.ToTitle(global.Cfg.Fdd.FddAppId) + md5Str + shaStr1)
	msgDigest := Base64(strings.ToTitle(shaStr2))
	param.AppId = global.Cfg.Fdd.FddAppId
	param.Timestamp = timeStr
	param.V = "2.0"
	param.MsgDigest = msgDigest
	//转为Map
	dataByte, _ := json.Marshal(&param)
	_ = json.Unmarshal(dataByte, &postData)
	//测试环境
	urlStr := "https://textapi.fadada.com/api2/get_person_verify_url.api"
	data, err := NewOnlineSig().PostWithFormData(urlStr, &postData, nil)
	if err != nil {
		return nil
	}
	//resData := data["data"].(map[string]interface{})
	////解码
	//decodeBytes, err := base64.StdEncoding.DecodeString(resData["url"].(string))
	//if err != nil {
	//	log.Fatalln(err)
	//}
	//fmt.Println(string(decodeBytes))

	return data

}

//请求法大大实名证书申请
func GetVerifyApplyCert(customerId string, verifiedSerialNo string) (map[string]interface{}, error) {
	param := request.ApplyCert{}
	postData := map[string]string{}

	param.CustomerId = customerId
	param.VerifiedSerialNo = verifiedSerialNo

	//获取MsgDigest
	shaStr1 := strings.ToTitle(SHA1(global.Cfg.Fdd.FddAppSecret + param.CustomerId + param.VerifiedSerialNo))
	timeStr := time.Now().Format("20060102030405")
	md5Str := strings.ToTitle(MD5(timeStr))
	shaStr2 := SHA1(strings.ToTitle(global.Cfg.Fdd.FddAppId) + md5Str + shaStr1)
	msgDigest := Base64(strings.ToTitle(shaStr2))
	param.AppId = global.Cfg.Fdd.FddAppId
	param.Timestamp = timeStr
	param.V = "2.0"
	param.MsgDigest = msgDigest
	//转为Map
	dataByte, _ := json.Marshal(&param)
	_ = json.Unmarshal(dataByte, &postData)

	//测试环境
	urlStr := "https://textapi.fadada.com/api2/apply_cert.api"
	data, err := NewOnlineSig().PostWithFormData(urlStr, &postData, nil)
	log.Println("请求法大大实名证书申请", data, customerId, verifiedSerialNo)
	if err != nil {
		return nil, err
	}
	return data, err
}

//查询个人实名认证信息
func GetFindPersonCertInfo(verifiedSerialno string) (map[string]interface{}, error) {

	param := &request.FindPersonCertInfo{}
	postData := map[string]string{}

	param.VerifiedSerialno = verifiedSerialno

	//获取MsgDigest
	shaStr1 := strings.ToTitle(SHA1(global.Cfg.Fdd.FddAppSecret + param.VerifiedSerialno))
	timeStr := time.Now().Format("20060102030405")
	md5Str := strings.ToTitle(MD5(timeStr))
	shaStr2 := SHA1(strings.ToTitle(global.Cfg.Fdd.FddAppId) + md5Str + shaStr1)
	msgDigest := Base64(strings.ToTitle(shaStr2))
	param.AppId = global.Cfg.Fdd.FddAppId
	param.Timestamp = timeStr
	param.V = "2.0"
	param.MsgDigest = msgDigest
	//转为Map
	dataByte, _ := json.Marshal(&param)
	_ = json.Unmarshal(dataByte, &postData)
	//测试环境
	urlStr := "https://textapi.fadada.com/api2/find_personCertInfo.api"
	data, err := NewOnlineSig().PostWithFormData(urlStr, &postData, nil)
	log.Println("查询个人实名认证信息", data)
	//获取状态
	resData := data["data"].(map[string]interface{})
	personData := resData["person"].(map[string]interface{})
	if personData["status"].(string) == "2" {
		return personData, nil
	}
	return nil, err
}

//模板填充
func GenerateContract(param request.GenerateContractParam, contractId string, docTitle string, templateId string) error {
	paramReq := &request.GenerateContract{}

	postData := map[string]string{}

	parameterMapByte, err := json.Marshal(param)
	parameterMapStr := string(parameterMapByte)

	paramReq.ParameterMap = parameterMapStr
	paramReq.ContractId = contractId
	paramReq.DocTitle = docTitle
	paramReq.TemplateId = templateId
	//获取MsgDigest
	shaStr1 := strings.ToTitle(SHA1(global.Cfg.Fdd.FddAppSecret + paramReq.TemplateId + paramReq.ContractId))
	timeStr := time.Now().Format("20060102030405")
	md5Str := strings.ToTitle(MD5(timeStr))
	shaStr2 := SHA1(strings.ToTitle(global.Cfg.Fdd.FddAppId) + md5Str + shaStr1 + parameterMapStr)
	msgDigest := Base64(strings.ToTitle(shaStr2))
	paramReq.AppId = global.Cfg.Fdd.FddAppId
	paramReq.Timestamp = timeStr
	paramReq.V = "2.0"
	paramReq.MsgDigest = msgDigest

	//转为Map
	dataByte, _ := json.Marshal(&paramReq)
	_ = json.Unmarshal(dataByte, &postData)

	//测试环境
	urlStr := "https://textapi.fadada.com/api2/generate_contract.api"
	data, err := NewOnlineSig().PostWithFormData(urlStr, &postData, nil)
	log.Println("模板填充返回信息", data)
	if data["result"] != "success" || err != nil {
		return err
	}
	return nil
}

//合同上传
func UploadDocs(contractId string, docTitle string, docUrl string) error {
	param := &request.UploadDocs{}
	postData := map[string]string{}

	param.ContractId = contractId
	param.DocTitle = docTitle
	param.DocUrl = docUrl
	param.DocType = ".pdf"
	//获取MsgDigest
	shaStr1 := strings.ToTitle(SHA1(global.Cfg.Fdd.FddAppSecret + param.ContractId))
	//md5Str := strings.ToTitle(MD5(time.Now().Format("20060102030405")))
	timeStr := time.Now().Format("20060102030405")
	md5Str := strings.ToTitle(MD5(timeStr))
	shaStr2 := SHA1(strings.ToTitle(global.Cfg.Fdd.FddAppId) + md5Str + shaStr1)
	msgDigest := Base64(strings.ToTitle(shaStr2))
	param.AppId = global.Cfg.Fdd.FddAppId
	param.Timestamp = timeStr
	param.V = "2.0"
	param.MsgDigest = msgDigest

	//转为Map
	dataByte, _ := json.Marshal(&param)
	_ = json.Unmarshal(dataByte, &postData)

	//测试环境
	urlStr := "https://textapi.fadada.com/api2/uploaddocs.api"
	data, err := NewOnlineSig().PostWithFormData(urlStr, &postData, nil)
	if data["result"] != "success" && err != nil {
		return err
	}
	return nil
}

//合同归档
func ContractIdFiling(contractId string) error {
	param := &request.ContractFiling{}
	postData := map[string]string{}

	param.ContractId = contractId

	//获取MsgDigest
	shaStr1 := strings.ToTitle(SHA1(global.Cfg.Fdd.FddAppSecret + param.ContractId))
	timeStr := time.Now().Format("20060102030405")
	md5Str := strings.ToTitle(MD5(timeStr))
	shaStr2 := SHA1(strings.ToTitle(global.Cfg.Fdd.FddAppId) + md5Str + shaStr1)
	msgDigest := Base64(strings.ToTitle(shaStr2))
	param.AppId = global.Cfg.Fdd.FddAppId
	param.Timestamp = timeStr
	param.V = "2.0"
	param.MsgDigest = msgDigest

	//转为Map
	dataByte, _ := json.Marshal(&param)
	_ = json.Unmarshal(dataByte, &postData)

	//测试环境
	urlStr := "https://textapi.fadada.com/api2/contractFiling.api"
	data, err := NewOnlineSig().PostWithFormData(urlStr, &postData, nil)
	if data["result"] != "success" && err != nil {
		return err
	}
	return nil

}
